package com.extrace.server.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.extrace.server.config.AjaxResult;
import com.extrace.server.dto.DataDTO;
import com.extrace.server.dto.ExpressDTO;
import com.extrace.server.dto.StartAndEndPosition;
import com.extrace.server.mapper.*;
import com.extrace.server.mapstruct.ExpressConvert;
import com.extrace.server.pojo.*;
import com.extrace.server.service.CustomerService;
import com.extrace.server.service.ExpressService;
import com.extrace.server.service.TranspackageService;
import com.extrace.server.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.swing.tree.TreeNode;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@CrossOrigin
@RestController
public class ExpressController {
    @Autowired
    ExpressService expressService;
    @Autowired
    CustomerService customerService;

    @Autowired
    TranspackageService transpackageService;

    @Autowired
    UserService userService;

    @Resource
    CustomerMapper customerMapper;

    @Resource
    ExpressMapper expressMapper;

    @Resource
    TransnodeMapper transnodeMapper;

    @Resource
    TranspackageMapper transpackageMapper;


    @Resource
    TranshistoryMapper transhistoryMapper;

    @Resource
    TranspackagecontentMapper transpackagecontentMapper;
    Map<String, String> provinceMap = Stream.of(new String[][] {
        {"11","北京"},
        {"12","天津"},
        {"31","上海"},
        {"50","重庆"},
        {"13","河北"},
        {"41","河南"},
        {"53","云南"},
        {"21","辽宁"},
        {"23","黑龙"},
        {"43","湖南"},
        {"34","安徽"},
        {"37","山东"},
        {"65","新疆"},
        {"32","江苏"},
        {"33","浙江"},
        {"36","江西"},
        {"42","湖北"},
        {"45","广西"},
        {"62","甘肃"},
        {"14","山西"},
        {"15","内蒙"},
        {"61","陕西"},
        {"22","吉林"},
        {"35","福建"},
        {"52","贵州"},
        {"44","广东"},
        {"63","青海"},
        {"54","西藏"},
        {"51","四川"},
        {"64","宁夏"},
        {"46","海南"},
    }).collect(Collectors.toMap(data -> data[0], data -> data[1]));
    /**
     *   获取每个 省份处理的 快件数量
     */
    @PostMapping ("/Domain/Express/getProvinceData")
    public AjaxResult getProvinceData(@RequestBody Map<String, Object> params) {
        List<ProvinceData> datas=expressMapper.getProvinceData();
        List<DataDTO> res = new ArrayList<>();
        for (ProvinceData provinceData : datas) {
            String name = provinceMap.get(provinceData.getProvinceCode());
            Integer value = provinceData.getCount();
            DataDTO dataDTO = new DataDTO();
            dataDTO.setName(name);
            dataDTO.setValue(value);
            res.add(dataDTO);
        }
        return AjaxResult.success(res);
    }




    /**
     *  查看当前快件的派送路线, 只是 派送的路线, 没有 大体的路线
     */
    @PostMapping ("/Domain/Express/getStartAndEndPosition2")
    public AjaxResult getStartAndEndPosition2(@RequestBody Map<String, Object> params) {
        List<Position> positions = new ArrayList<>();
        String eid=(String) params.get("id");
        positions.addAll(transhistoryMapper.selectList(new LambdaQueryWrapper<Transhistory>().eq(Transhistory::getEid,eid)).stream().map(transhistory -> {
            Position position = new Position();
            position.setLon(transhistory.getLon());
            position.setLat(transhistory.getLat());
            return position;
        }).collect(Collectors.toList()));
        return AjaxResult.success(positions);
    }



    /**
     *  查看当前快件的起始位置, 只是大体的路线, 不包含派送的路线
     */
    @PostMapping ("/Domain/Express/getStartAndEndPosition")
    public AjaxResult getStartAndEndPosition(@RequestBody Map<String, Object> params) {
        List<Position> positions = new ArrayList<>();
        String eid=(String) params.get("id");
        String startRegionCode= eid.substring(1, 7);
        startRegionCode+="00";
        List<String> transpakgeIdList=transpackagecontentMapper.selectPackageIdsByEid(eid);
        if(transpakgeIdList.size()==0){ // 还没有开始打包, 就是刚下单
            Transnode transnode = transnodeMapper.selectById(startRegionCode);
            Position p = new Position();
            p.setLon(transnode.getLon());
            p.setLat(transnode.getLat());
            positions.add(p);
            return AjaxResult.success(positions);
        }
        Set<String> nodes=new HashSet<>();
        List<String> nodeList = new ArrayList<>();
        List<Transpackage> transpackages = transpackageMapper.selectList(new LambdaQueryWrapper<Transpackage>().in(Transpackage::getId,transpakgeIdList).orderByAsc(Transpackage::getCreateTime));
        for (Transpackage transpackage : transpackages) {
            if(!nodes.contains(transpackage.getStartNode())){
                nodeList.add(transpackage.getStartNode());
            }
            nodes.add(transpackage.getStartNode());
            if(transpackage.getEnder()!=null){
                if(!nodes.contains(transpackage.getEndNode())){
                    nodeList.add(transpackage.getEndNode());
                }
                nodes.add(transpackage.getEndNode());
            }
        }
        positions = transnodeMapper.selectList(new LambdaQueryWrapper<Transnode>().in(Transnode::getId,nodeList).last("ORDER BY FIELD(id, " + nodeList.stream().map(String::valueOf).collect(Collectors.joining(",")) + ")")).stream().map(transnode -> {
            Position position = new Position();
            position.setLon(transnode.getLon());
            position.setLat(transnode.getLat());
            return position;
        }).collect(Collectors.toList());
        return AjaxResult.success(positions);
    }




    /**
     *  管理员查询快件信息
     */
    @PostMapping("/Domain/Express/findExpressList")
    public List<Express> findExpressList(@RequestBody Map<String, Object> params) {

        LambdaQueryWrapper<Customer> senderLambdaQueryWrapper=new LambdaQueryWrapper<>();
        if(params.containsKey("senderName") && StringUtils.hasLength(String.valueOf(params.get("senderName")))){
            senderLambdaQueryWrapper.eq(Customer::getName, params.get("senderName"));
        }

        if(params.containsKey("senderAddressCode")&& StringUtils.hasLength(String.valueOf(params.get("senderAddressCode")))){
            senderLambdaQueryWrapper.eq(Customer::getRegionCode, params.get("senderAddressCode"));
        }

        LambdaQueryWrapper<Customer> receiverLambdaQueryWrapper=new LambdaQueryWrapper<>();
        if(params.containsKey("receiverName") && StringUtils.hasLength(String.valueOf(params.get("receiverName")))){
            receiverLambdaQueryWrapper.eq(Customer::getName, params.get("receiverName"));
        }

        if(params.containsKey("receiverAddressCode")&& StringUtils.hasLength(String.valueOf(params.get("receiverAddressCode")))){
            receiverLambdaQueryWrapper.eq(Customer::getRegionCode, params.get("receiverAddressCode"));
        }


        List<Customer> senders=customerMapper.selectList(senderLambdaQueryWrapper);
        // 查找收件人
        List<Customer> receivers = customerMapper.selectList(receiverLambdaQueryWrapper);
        if(receivers.isEmpty() || senders.isEmpty()){
            return new ArrayList<>(); // 没有数据
        }

        // 所有发件人的 id
        List<Integer> senderIds = senders.stream().map(Customer::getId).collect(Collectors.toList());
        // 所有收件人的 Id
        List<Integer> receiverIds = receivers.stream().map(Customer::getId).collect(Collectors.toList());

        LambdaQueryWrapper<Express> expressLambdaQueryWrapper=new LambdaQueryWrapper<>();
        if(params.containsKey("eid")&& StringUtils.hasLength((String.valueOf(params.get("eid"))))){
            expressLambdaQueryWrapper.eq(Express::getId, params.get("eid"));
        }

        // 查找本人的, 并且收件人是指定人名的 express
        expressLambdaQueryWrapper.in(Express::getSender, senderIds);
        expressLambdaQueryWrapper.in(Express::getReceiver, receiverIds);

        List<Express> expressList = expressMapper.selectList(expressLambdaQueryWrapper);
        for (Express e: expressList) {
            e.setSnd(customerMapper.selectById(e.getSender()));
            e.setRcv(customerMapper.selectById(e.getReceiver()));
        }

        return expressList;
    }




    /**
     *  查看当前角色权限
     */
    @PostMapping ("/Domain/Express/getRoleId")
    public AjaxResult getRoleId() {
        System.out.println("------------------------------------");
        User currentUser = userService.getCurrentUser();
        if(currentUser==null){
            return AjaxResult.error("用户未登录");
        }
        return AjaxResult.success(currentUser.getRid());
//        return AjaxResult.success(1);
    }


    /**
     *  快递员查询是否有新的待揽收的快件
     */
    @PostMapping ("/Domain/Express/inquiryNewWaitCollectExpress")
    public AjaxResult inquiryNewWaitCollectExpress() {
        System.out.println("------------------------------------");
        User currentUser = userService.getCurrentUser();
        if(currentUser==null){
            return AjaxResult.error("用户未登录");
        }
        // 获取网点的 id
        String nid=currentUser.getNid();
        // 获取 网点的 regionCode
        String regionCode=transnodeMapper.selectById(nid).getRegionCode();
        // 获取没有通知过的列表
        List<Express> expressList=expressMapper.selectNewWaitCollect(regionCode);
        int size = expressList.size();
        // 更新已经通知过的列表
        for (Express e: expressList) {
            e.setNotified(1);
            expressMapper.updateById(e);
        }
        if(size>0){
            return AjaxResult.success(1);
        } else {
            return AjaxResult.success(0);
        }
    }


    /**
     *  快递员查看收件人的地址码
     */
    @PostMapping ("/Domain/Express/getExpressEndAddressCode/{eid}")
    public AjaxResult getExpressEndAddressCode(@PathVariable String eid) {
        System.out.println("------------------------------------");
        User currentUser = userService.getCurrentUser();
        if(currentUser==null){
            return AjaxResult.error("用户未登录");
        }
        Express express = expressMapper.selectById(eid);
        Customer rcv = customerMapper.selectById(express.getReceiver());
        return AjaxResult.success(rcv.getRegionCode());
    }




    /**
     *  快递员查看待揽收列表
     */
    @PostMapping("/Domain/Express/getWaitCollectList")
    public AjaxResult checkWaitingList() {
        User currentUser = userService.getCurrentUser();
        if(currentUser==null){
            return AjaxResult.error("用户未登录");
        }
        // 获取网点的 id
        String nid=currentUser.getNid();
        // 获取 网点的 regionCode
        String regionCode=transnodeMapper.selectById(nid).getRegionCode();
        List<Express> expressList=expressMapper.selectByRegionCode(regionCode);
        for(Express e: expressList){
            Customer customer = customerMapper.selectById(e.getSender());
            System.out.println(customer);
            e.setSnd(customer);
            e.setRcv(customerMapper.selectById(e.getReceiver()));
        }
        return AjaxResult.success(expressList);
    }

    /**
     *  快递员查看处理过的包裹
     */
    @PostMapping("/Domain/Express/getProcessedList")
    public AjaxResult getProcessedList(@RequestParam Integer type) {
        User currentUser = userService.getCurrentUser();
        if(currentUser==null){
            return AjaxResult.error("用户未登录");
        }
        // 判断人员类型
        if(currentUser.getRid()==1){ // 区级网点, 可以进行揽收和派送的查询
            if(type==1){// 揽收的
                return AjaxResult.success(expressService.findByPicker(currentUser.getId(), null));
            } else{ // 派送的
                return AjaxResult.success(expressService.findByDeliver(currentUser.getId(), null));
            }
        } else { // 其他级网点, 进行打包的查询
            return AjaxResult.success(transpackageService.findByPacker(currentUser.getId(), null));
        }
    }


    /**
     *  用户取消订单
     */
    @PostMapping("/Domain/Express/cancelOrder")
    public AjaxResult cancelOrder(@RequestBody Map<String, Object> params) {
        Customer currentCustomer = customerService.getCurrentCustomer();
        if(currentCustomer==null){
            return AjaxResult.error("未登录"); // 未登录
        }
        Express express = expressMapper.selectById((String) params.get("id"));
        express.setStatus(-1);
        int cnt=expressMapper.updateById(express);
        return AjaxResult.success(cnt);
    }

    /**
     *  用户删除历史订单
     */
    @PostMapping("/Domain/Express/deleteOrder")
    public Integer deleteOrder(@RequestBody Map<String, Object> params) {
        Customer currentCustomer = customerService.getCurrentCustomer();
        if(currentCustomer==null){
            return -1; // 未登录
        }
        String id=(String) params.get("id");

        return expressMapper.deleteById(id);
    }

    @PostMapping("/Domain/Express/viewOrder")
    public AjaxResult viewOrder(@RequestBody Map<String, Object> params) {
        Customer currentCustomer = customerService.getCurrentCustomer();
        if(currentCustomer==null){
            return AjaxResult.error("未登录"); // 未登录
        }
        String id=(String) params.get("id");
        Express express = expressMapper.selectById(id);
        express.setSnd(customerMapper.selectById(express.getSender()));
        express.setRcv(customerMapper.selectById(express.getReceiver()));
        return AjaxResult.success(express);
    }




    /**
     *  对派送人员进行评分
     */
    @PostMapping("/Domain/Express/giveScore")
    public AjaxResult giveScore(@RequestBody Map<String, Object> params) {
        Express express = expressMapper.selectById((String)params.get("id"));
        express.setStatus(9);
        express.setScore((Integer) params.get("score"));
        return AjaxResult.success(expressMapper.updateById(express));
    }

    /**
     *  修改订单的地址
     */
    @PostMapping("/Domain/Express/modifyOrder")
    public AjaxResult modifyReceiverAddress(@RequestBody ExpressDTO expressDTO, HttpServletResponse response) {
        Express express = ExpressConvert.INSTANCE.dto2po(expressDTO);
        Customer sender = customerMapper.selectById(express.getSender());
        Customer receiver = customerMapper.selectById(express.getReceiver());
        // 更新发送方
        sender.setName(expressDTO.getSenderName());
        sender.setRegionCode(expressDTO.getSenderAddressCode());
        sender.setAddress(expressDTO.getSenderDetailAddress());
        sender.setTelCode(expressDTO.getSenderTel());
        customerMapper.updateById(sender);
        // 更新接收方
        receiver.setName(expressDTO.getReceiverName());
        receiver.setRegionCode(expressDTO.getReceiverAddressCode());
        receiver.setAddress(expressDTO.getReceiverDetailAddress());
        receiver.setTelCode(expressDTO.getReceiverTel());
        customerMapper.updateById(receiver);
        // 更新订单
        int cnt = expressMapper.updateById(express);
        return AjaxResult.success(cnt);
    }

    @GetMapping("/Domain/Express/pickExpress/{id}")
    public Express pickExpress(@PathVariable String id, HttpServletResponse response) {
        Express express = expressService.pickExpressById(id, response);
        return express;
    }
    @GetMapping("/Domain/Express/deliverExpress/{id}")
    public Express deliverExpress(@PathVariable String id, HttpServletResponse response) {
        Express express = expressService.deliverExpressById(id, response);
        return express;
    }
   @GetMapping("Domain/Express/signExpress")
   public boolean signExpress(String eId,String cTel,HttpServletResponse response){
        Customer cs = customerService.findByTelCode(cTel);
        if (cs == null){
            response.setHeader("state","customer_empty");
            return false;
        }else{
            if(expressService.signExpress(eId,cs.getId(),response)){
                return true;
            }else{
                return false;
            }
        }
   }
    @GetMapping("/Domain/Express/getExpressList")
    public List<Express> getExpressList(HttpServletResponse response) {
        return expressService.findAll();
    }
    @PostMapping("/Domain/Express/saveExpress")
    public Express saveExpress(@RequestBody ExpressDTO expressDTO, HttpServletResponse response){
        // 先创建两个用户
        Customer customer1 = new Customer();
        Customer customer2 = new Customer();
        customer1.setName(expressDTO.getSenderName());
        customer2.setName(expressDTO.getReceiverName());
        customer1.setTelCode(expressDTO.getSenderTel());
        customer2.setTelCode(expressDTO.getReceiverTel());
        customer1.setRegionCode(expressDTO.getSenderAddressCode());
        customer2.setRegionCode(expressDTO.getReceiverAddressCode());
        customer1.setAddress(expressDTO.getSenderDetailAddress());
        customer2.setAddress(expressDTO.getReceiverDetailAddress());
        // 需要查询一下是否存在两个一摸一样的用户, 这里就先不查询了, 其实有很大 bug的
        // 比如说 这里面保存之后, 后面相同的用户名就不能注册了
        customer1.setRegistered(0);
        customer2.setRegistered(0);
        // 然后设置 express
        Express express = ExpressConvert.INSTANCE.dto2po(expressDTO);
        // 把两个用户保存一下
        express.setSender(customerService.save(customer1).getId());
        express.setReceiver(customerService.save(customer2).getId());
        // 同时还需要记录下单的人的 id , 以便后面 查询该用户的所有订单
        Customer customer=customerService.getCurrentCustomer();
        express.setCustomerId(customer.getId());
        express.setNotified(0);
        express.setDeleteFlag(0);
        // 设置路线的类型
//        String sndCode = expressDTO.getSenderAddressCode();
//        String rcvCode = expressDTO.getReceiverAddressCode();
//        // 获取路线的类型 同一个市 同一个省 跨省
//        if(sndCode.substring(0, 2).equals(rcvCode.substring(0, 2))){ // 省级
//            if(sndCode.substring(0, 4).equals(rcvCode.substring(0, 4))){
//                express.setRouteType(1); // 同市
//            } else {
//                express.setRouteType(2); // 同省
//            }
//        } else {
//            express.setRouteType(3); // 跨省
//        }

        String emptyExpreessId = expressService.findEmptyId(express.getSender());
        if(emptyExpreessId == null){
            response.addHeader("state","create_fail");
            return express;
        }
        else{
            express.setId(emptyExpreessId);
            expressService.save(express);
            response.addHeader("state","create_success");
            return express;
        }
    }
    @GetMapping("/Domain/Express/getExpressesByPid/{pid}")
    public List<Express> getExpressesByPid(@PathVariable String pid, HttpServletResponse response) {
        return expressService.getExpressesByPid(pid, response);
    }
    @GetMapping("/Domain/Express/getPermitExpressListByPid/{pid}")
    public List<Express> getPermitExpressListByPid(@PathVariable String pid,HttpServletResponse response){
        return expressService.getPermitExpressListByPid(pid, response);
    }
    @GetMapping("/Domain/Express/getFreeExpressList")
    public List<Express> getFreeExpressList(HttpServletResponse response){
        if(expressService.getFreeExpressList() != null){
            response.addHeader("state","read_success");
            return expressService.getFreeExpressList();
        }else{
            response.addHeader("state","read_fail");
            return null;
        }
    }
    @GetMapping("/Domain/Express/getExpress/{id}")
    public Express getExpress(@PathVariable String id, HttpServletResponse response,HttpServletResponse request){
        Express express = expressService.findById(id);
        expressService.addInfo(express);
        if(express == null){
            response.addHeader("state","read_fail");
            return null;
        }
        response.addHeader("state","read_success");
        return express;
    }
    @GetMapping("/Domain/Express/getWaitDeliverExpressList")
    public List<Express> getWaitDeliverExpressList(HttpServletResponse response){
        return expressService.getWaitDeliverExpressList(response);
    }
    @GetMapping("/Domain/Express/getExpressTrackList/{id}")
    public List<ExpressTrack> getExpressTrackList(@PathVariable String id, HttpServletResponse response) {
        List<ExpressTrack> expressTrackList = expressService.getExpressTrackList(id, response);
        if (expressTrackList != null && !expressTrackList.isEmpty()) {
            expressTrackList.get(0).setType(ExpressTrack.STATUS.TYPE_CURRENT);
        }
        return expressTrackList;
    }


    /**
     *  获取个人历史订单
     */
    @PostMapping("/Domain/Express/getPersonalExpressList")
    public List<Express> getExpressTrackList(@RequestBody Map<String, Object> params) {
        Customer currentCustomer = customerService.getCurrentCustomer();
        if(currentCustomer==null){
            return new ArrayList<>(); // 未登录
        }

        LambdaQueryWrapper<Customer> customerLambdaQueryWrapper=new LambdaQueryWrapper<>();
        if(params.containsKey("receiverName") && StringUtils.hasLength(String.valueOf(params.get("receiverName")))){
            customerLambdaQueryWrapper.like(Customer::getName, params.get("receiverName"));
        }

        if(params.containsKey("receiverAddressCode")&& StringUtils.hasLength(String.valueOf(params.get("receiverAddressCode")))){
            customerLambdaQueryWrapper.like(Customer::getRegionCode, params.get("receiverAddressCode"));
        }
        // 查找收件人
        List<Customer> receivers = customerMapper.selectList(customerLambdaQueryWrapper);
        if(receivers.isEmpty()){
            return new ArrayList<>(); // 没有数据
        }
        // 所有收件人的 Id
        List<Integer> receiverIds = receivers.stream().map(Customer::getId).collect(Collectors.toList());

        LambdaQueryWrapper<Express> expressLambdaQueryWrapper=new LambdaQueryWrapper<>();
        if(params.containsKey("id")&& StringUtils.hasLength((String.valueOf(params.get("id"))))){
            expressLambdaQueryWrapper.eq(Express::getId, params.get("id"));
        }
        if(params.containsKey("createTime")&& StringUtils.hasLength(String.valueOf(params.get("createTime")))){
            expressLambdaQueryWrapper.ge(Express::getCreateTime, params.get("createTime"));
        }

        if(params.containsKey("status")&& StringUtils.hasLength(String.valueOf(params.get("status")))){
            expressLambdaQueryWrapper.eq(Express::getStatus, params.get("status"));
        }

        // 查找本人的, 并且收件人是指定人名的 express
        expressLambdaQueryWrapper.eq(Express::getCustomerId, currentCustomer.getId());
        expressLambdaQueryWrapper.in(Express::getReceiver, receiverIds);

        List<Express> personalExpressList = expressMapper.selectList(expressLambdaQueryWrapper);
        for (Express e: personalExpressList) {
            e.setSnd(customerMapper.selectById(e.getSender()));
            e.setRcv(customerMapper.selectById(e.getReceiver()));
        }

        return personalExpressList;
    }


}
